package com.cooper.service.item;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.cooper.constants.ResourceConstants;
import com.cooper.core.JsonResult;
import com.cooper.domain.ImageItem;
import com.cooper.domain.PackageItem;
import com.cooper.entity.ItemImage;
import com.cooper.entity.ItemInfo;
import com.cooper.entity.ItemSku;
import com.cooper.entity.ItemStatEntity;
import com.cooper.entity.UserInfo;
import com.cooper.helper.ItemExtendHelper;
import com.cooper.pagination.PageInfo;
import com.cooper.pagination.PageResult;
import com.cooper.service.admin.AddressService;
import com.cooper.util.Controllers;
import com.cooper.util.StringUtils;
import com.cooper.vo.AddressVo;
import com.cooper.vo.ItemInfoVo;
import com.cooper.vo.ItemSearchVo;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;

@Repository
public class ItemRepository extends ItemInfoService {
	
	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	
	public static final String ITEM_SEARCH_OBJECT = "item_1001";
	
	@Autowired
	private AddressService addressService;
	
	@Autowired
	private ItemSkuService itemSkuService;
	
	@Autowired
	private ItemImageService itemImageService;
	
	@Autowired
	private ItemStatService itemStatService;
	
	@SuppressWarnings("unchecked")
	public PageResult<ItemInfoVo> doSearch(ItemSearchVo searchVo, PageInfo pageInfo) throws Exception{
		int rowCount = this.queryItemInfoCount(null, searchVo);
		pageInfo.setRowCount(rowCount);
		if (rowCount <= pageInfo.getStartIndex()) {
			return new PageResult<ItemInfoVo>(Collections.EMPTY_LIST, pageInfo);
		}
		
		List<ItemInfoVo> dataList = this.queryItemInfoList(null, searchVo, pageInfo);
		return new PageResult<ItemInfoVo>(dataList, pageInfo);
	}
	
	public String getItemMainUrl(long itemId) throws Exception{
		List<ItemImage> itemImageList = this.itemImageService.getItemImageListByItemId(itemId);
		if(CollectionUtils.isEmpty(itemImageList)){
			return "";
		} else {
			return itemImageList.get(0).getOriginUrl();
		}
	}
	
	@SuppressWarnings("unchecked")
	public PageResult<ItemInfoVo> queryForList(Long userId, ItemSearchVo searchVo, PageInfo pageInfo) throws Exception{
		int rowCount = this.queryItemInfoCount(userId, searchVo);
		pageInfo.setRowCount(rowCount);
		if (rowCount <= pageInfo.getStartIndex()) {
			return new PageResult<ItemInfoVo>(Collections.EMPTY_LIST, pageInfo);
		}
		List<ItemInfoVo> dataList = this.queryItemInfoList(userId, searchVo, pageInfo);
		return new PageResult<ItemInfoVo>(dataList, pageInfo);
	}
	
	@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
	public JsonResult saveItem(UserInfo userInfo, ItemInfo itemInfo, ItemExtendHelper helper) throws Exception{
		JsonResult json = new JsonResult();
		List<PackageItem> packageList = JSON.parseArray(helper.getStrSkuArray(), PackageItem.class);
		int totalQuantity = 0;
		if(CollectionUtils.isEmpty(packageList)){
			json.setMessage("PACKAGE ITEMS CAN'T BE EMPTY.");
			return json;
		} else {
			for(PackageItem packageItem: packageList){
				totalQuantity += packageItem.getPackageQuantity();
			}
		}
		
		List<ImageItem> imageList = JSON.parseArray(helper.getStrImageArray(), ImageItem.class);
		if(CollectionUtils.isEmpty(imageList)){
			json.setMessage("ITEM IMAGES CAN'T BE EMPTY.");
			return json;
		}
		
		boolean bUpdate = null != itemInfo && null != itemInfo.getId();
		Controllers.prepareEntityForDataSaving(itemInfo, userInfo, bUpdate);
		itemInfo.setSellerId(userInfo.getId());
		itemInfo.setQuantity(totalQuantity);
		itemInfo.setDeliverFreight(0.0);
		itemInfo.setDeliverTariff(0.0);
		if(null == itemInfo.getDiscountPercent()){
			itemInfo.setDiscountVolume(Double.valueOf(0));
			itemInfo.setDiscountPercent(Double.valueOf(0));
		}
		
		long itemId = 0L;
		if(bUpdate){
			itemId = itemInfo.getId();
			this.updateEntity(itemInfo);
		} else {
			itemId = this.saveEntity(itemInfo);
			
			//save item statistics
			ItemStatEntity itemStat = new ItemStatEntity();
			itemStat.setItemId(itemId);
			this.itemStatService.saveEntity(itemStat);
		}
		
		Collection<Long> skuIdList = Collections2.transform(packageList, new Function<PackageItem, Long>(){
			@Override
			public Long apply(PackageItem input) {
				return input.getPackageId();
			}
		});
		this.itemSkuService.deleteSkusNotUsedByItemId(itemId, skuIdList);
		
		//save item skus
		for(PackageItem packageItem: packageList){
			ItemSku itemSku = null;
			boolean updated = false;
			if(StringUtils.isLongValid(packageItem.getPackageId())){
				itemSku = this.itemSkuService.loadById(packageItem.getPackageId());
				updated = true;
			} else {
				itemSku = new ItemSku();
				itemSku.setItemId(itemId);
			}
			
			Controllers.prepareEntityForDataSaving(itemSku, userInfo, updated);
			itemSku.setProperties(packageItem.getPackageName());
			itemSku.setQuantity(packageItem.getPackageQuantity());
			itemSku.setPrice(packageItem.getPackagePrice());
			if(updated){
				this.itemSkuService.updateEntity(itemSku);
			} else {
				this.itemSkuService.saveEntity(itemSku);
			}
		}
		
		Collection<Long> imageIdList = Collections2.transform(imageList, new Function<ImageItem, Long>(){
			@Override
			public Long apply(ImageItem input) {
				return input.getId();
			}
		});
		this.itemImageService.deleteImagesNotUsedByItemId(itemId, imageIdList);
		
		//save item images
		for(int index=0; index < imageList.size(); index++){
			ImageItem img = imageList.get(index);
			ItemImage itemImage = null;
			boolean updated = false;
			if(StringUtils.isLongValid(img.getId())){
				itemImage = this.itemImageService.loadById(img.getId());
				updated = true;
			} else {
				itemImage = new ItemImage();
				itemImage.setItemId(itemId);
			}
			Controllers.prepareEntityForDataSaving(itemImage, userInfo, updated);
			itemImage.setSortNo(index+1);
			if(!img.getSrc().equals(itemImage.getOriginUrl())){
				//TODO change thumb images
			}
			itemImage.setOriginUrl(img.getSrc());
			if(updated){
				this.itemImageService.updateEntity(itemImage);
			} else {
				this.itemImageService.saveEntity(itemImage);
			}
		}
		
		//save item origin
		AddressVo addressVo = new AddressVo();
		addressVo.setStrLocationIds(helper.getOriginIds());
		addressVo.setStrLocationNames(helper.getOriginNames());
		addressVo.setOrigin(ResourceConstants.AddressOrigin.ITEM_ORIGIN);
		addressVo.setOuterId(itemId);
		this.addressService.saveAddress(addressVo);
		
		json.setSuccess(true);
		return json;
	}
}

